/*
 * 文件名： WechatScanPayServiceImpl.java
 * 
 * 工程名称: bis-service
 *
 * Gopay
 *
 * 创建日期： 2016年8月5日
 *
 * Copyright(C) 2016, by www.gopay.com.cn Inc.All rights reserved.
 *
 * 原始作者: 宣广海
 *
 */
package com.gopay.bis.service.bank.impl.scan;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.manager.bank.scan.CmbcWechatScanPayManager;
import com.gopay.bis.service.bank.BankIntrChannConfService;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.wechat.scan.cmbc.FetchCheckAccntFile;
import com.gopay.common.domain.bank.wechat.scan.cmbc.FileDownReq;
import com.gopay.common.domain.bank.wechat.scan.cmbc.Head;
import com.gopay.common.domain.bank.wechat.scan.cmbc.MerchantModify;
import com.gopay.common.domain.bank.wechat.scan.cmbc.MerchantOperation;
import com.gopay.common.domain.bank.wechat.scan.cmbc.MerchantOperationQuery;
import com.gopay.common.domain.bank.wechat.scan.cmbc.MerchantQuery;
import com.gopay.common.domain.bank.wechat.scan.cmbc.MerchantSettled;
import com.gopay.common.domain.bank.wechat.scan.cmbc.ScanPay;
import com.gopay.common.domain.bank.wechat.scan.cmbc.TradeQuery;
import com.gopay.common.domain.bank.wechat.scan.cmbc.TransMsg;
import com.gopay.common.domain.bank.wechat.scan.res.ScanPayResultMsg;
import com.gopay.common.domain.bank.wechat.scan.res.ScanPayServerNotifyMsg;
import com.gopay.common.domain.bis.BaseBisBankExtConfig;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.ScanPayInteractRemoteService;
import com.gopay.remote.bank.ScanPayMerchantService;

/**
 * 民生扫码支付业务实现
 * 
 * @author jiangxiangjiao
 * @version
 */
@SuppressWarnings("all")
public class CmbcWechatScanPayServiceImpl implements ScanPayInteractRemoteService, ScanPayMerchantService {

	private static Logger logger = LoggerFactory.getLogger(CmbcWechatScanPayServiceImpl.class);

	@Resource(name = "cmbcWechatScanPayManager")
	private CmbcWechatScanPayManager cmbcWechatScanPayManager;
	@Resource(name = "bankIntrChannConfService")
	private BankIntrChannConfService bankIntrChannConfService;

	@Override
	public Result pay(BaseMessage msg) throws GopayException {
		Result result = new Result(false);
		try {
			TransMsg<ScanPay> resMessage = (TransMsg) cmbcWechatScanPayManager.scanPay(msg);
			logger.info("---民生扫码支付返回处理对象：" + ToStringBuilder.reflectionToString(resMessage));
			ScanPay scanPayResult = (ScanPay) resMessage.getBody();

			ScanPayResultMsg respMsg = new ScanPayResultMsg();
			BeanUtils.copyProperties(resMessage, respMsg);
			if (resMessage != null && StringUtils.equalsIgnoreCase("R", resMessage.getHead().getRespType())
					&& StringUtils.isNotBlank(scanPayResult.getQrCode())) {
				respMsg.setCodeUrl(scanPayResult.getQrCode());
				respMsg.setCodeImage(scanPayResult.getQrCode());

				respMsg.setCode_url(scanPayResult.getQrCode());
				respMsg.setCode_img_url(scanPayResult.getQrCode());

				result.setDefaultModel(respMsg); // 收银台从ScanPayBaseMessage类获取支付请求结果
				result.setSuccess(true);
			} else {
				result.setResultCode(ProcCodeConstants.PROC_CODE_100E1153);
				result.setErrorMsg(resMessage.getHead().getRespMsg());
				result.setSuccess(false);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E1153);
		}
		return result;
	}

	@Override
	public Result orderQuery(BaseMessage msg) throws GopayException {
		Result result = new Result();
		try {
			TransMsg<TradeQuery> resultMsg = (TransMsg) cmbcWechatScanPayManager.orderQuery(msg);
			logger.info("---民生扫码订单查询返回处理对象：" + ToStringBuilder.reflectionToString(resultMsg));
			TradeQuery query = (TradeQuery) resultMsg.getBody();
			if (null == query.getTotalAmount()) {
				resultMsg.setAmount(msg.getAmount());
			} else {
				resultMsg.setAmount(query.getTotalAmount());
			}
			result.setDefaultModel(resultMsg);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		return result;
	}

	@Override
	public Result refund(BaseMessage msg) throws GopayException {
		Result result = new Result();
		try {
		TransMsg<TradeQuery> resultMsg = (TransMsg) cmbcWechatScanPayManager.refund(msg);
		logger.info("---民生扫码退款返回处理对象：" + ToStringBuilder.reflectionToString(resultMsg));
		Map<String, String> param = new HashMap<String, String>();
		if (resultMsg != null) {
			if (!"E".equals(resultMsg.getHead().getRespType())) {
				result.setDefaultModel(resultMsg);
				result.setSuccess(true);
				// 接收成功
				result.setModel("falg", true);
			} else {
				result.setSuccess(false);
				result.setModel("falg", false);
				result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
				result.setErrorMsg(resultMsg.getHead().getRespMsg());
			}
		} else {
			result.setSuccess(false);
			result.setModel("falg", false);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
		}
		}catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
		}
		return result;
	}

	@Override
	public Result refundQuery(BaseMessage msg) throws GopayException {

		Result result = new Result(false);
		try {
			TransMsg<TradeQuery> resultMsg = (TransMsg) cmbcWechatScanPayManager.orderQuery(msg);
			logger.info("---民生扫码订单查询返回处理对象：" + ToStringBuilder.reflectionToString(resultMsg));
			TradeQuery query = (TradeQuery) resultMsg.getBody();
			if (null == query.getTotalAmount()) {
				resultMsg.setAmount(msg.getAmount());
			} else {
				resultMsg.setAmount(query.getTotalAmount());
			}
			result.setDefaultModel(resultMsg);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		return result;
	}

	@Override
	public Result verify(BaseMessage msg) throws GopayException {
		Result result = new Result(false);
		ScanPayServerNotifyMsg message = (ScanPayServerNotifyMsg) msg;
		TransMsg verifyMsg = new TransMsg();
		BeanUtils.copyProperties(message, verifyMsg);
		Boolean flag = (Boolean) cmbcWechatScanPayManager.verify(verifyMsg);
		result.setDefaultModel(flag);
		result.setSuccess(true);
		result.setModel("res", msg);
		Map<String, String> param = new HashMap<String, String>();
		// 验签成功
		if ((boolean) result.getDefaultModel()) {
			if (("0".equals(message.getPay_result()))) {
				param.put("orderId", message.getOrderId());
				param.put("amt", String.valueOf(message.getAmount()));
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "00");
				param.put("retCode", "00");
				param.put("retMsg", "验签成功");
				param.put("signData", "");
				param.put("isFront", String.valueOf(message.isFront()));
				result.setModel("isNotifyCashier", param);
				result.setOrderStatus(true);
			} else {
				param.put("orderId", message.getOrderId());
				param.put("amt", String.valueOf(message.getAmount()));
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "01");
				param.put("retCode", "01");
				param.put("retMsg", "验签失败");
				param.put("signData", "");
				param.put("isFront", String.valueOf(message.isFront()));
				result.setModel("isNotifyCashier", param);
				result.setOrderStatus(false);
			}
		}
		return result;
	}

	@Override
	public Result merchantSettled(Object msg) throws GopayException {
		BaseBisBankExtConfig bankConfig = bankIntrChannConfService.findBaseBisBankExtConfigByBankChannel(
				BisBankBusinessProd._16, BisBankInterfaceChannel._17, BankConstants.BANK_LOGO_WECHAT);
		MerchantSettled request = (MerchantSettled) msg;
		TransMsg<MerchantSettled> response = (TransMsg) cmbcWechatScanPayManager.merchantSettled(request,
				generateParam(bankConfig));
		logger.info("---民生扫码商户入驻返回处理对象：" + ToStringBuilder.reflectionToString(response));
		Result result = new Result();
		result.setDefaultModel(response.getBody());
		Head head = response.getHead();
		if (StringUtils.equalsIgnoreCase("S", head.getRespType())) {
			result.setSuccess(true);
			result.setOrderStatus(true);
		}if(StringUtils.equalsIgnoreCase("R", head.getRespType())){
			result.setSuccess(true);
			result.setOrderStatus(false);
			result.setErrorMsg(head.getRespMsg());
			result.setResultCode(head.getRespCode());
		}
		else {
			result.setSuccess(false);
			result.setOrderStatus(false);
			result.setErrorMsg(head.getRespMsg());
			result.setResultCode(head.getRespCode());
		}
		return result;
	}

	@Override
	public Result merchantQuery(Object msg) throws GopayException {
		BaseBisBankExtConfig bankConfig = bankIntrChannConfService.findBaseBisBankExtConfigByBankChannel(
				BisBankBusinessProd._16, BisBankInterfaceChannel._17, BankConstants.BANK_LOGO_WECHAT);

		MerchantQuery request = (MerchantQuery) msg;
		TransMsg<MerchantQuery> response = (TransMsg) cmbcWechatScanPayManager.merchantQuery(request,
				generateParam(bankConfig));
		logger.info("---民生扫码商户查询返回处理对象：" + ToStringBuilder.reflectionToString(response));
		Result result = new Result();
		result.setDefaultModel(response.getBody());
		Head head = response.getHead();
		if (StringUtils.equalsIgnoreCase("S", head.getRespType())) {
			/**
			 * 判断审核失败的情况
			 */
			if(StringUtils.equalsIgnoreCase("S", response.getBody().getOriRespType())){
				result.setSuccess(true);
			}else{
				result.setErrorMsg(response.getBody().getOriRespMsg());
				result.setResultCode(response.getBody().getOriRespCode());
			}		
		} else {
			result.setErrorMsg(head.getRespMsg());
			result.setResultCode(head.getRespCode());
		}
		return result;
	}

	@Override
	public Result merchantModify(Object msg) throws GopayException {
		BaseBisBankExtConfig bankConfig = bankIntrChannConfService.findBaseBisBankExtConfigByBankChannel(
				BisBankBusinessProd._16, BisBankInterfaceChannel._17, BankConstants.BANK_LOGO_WECHAT);

		MerchantModify request = (MerchantModify) msg;
		TransMsg<MerchantModify> response = (TransMsg) cmbcWechatScanPayManager.merchantModify(request,
				generateParam(bankConfig));
		logger.info("---民生扫码商户修改返回处理对象：" + ToStringBuilder.reflectionToString(response));
		Result result = new Result();
		result.setDefaultModel(response.getBody());
		Head head = response.getHead();
		if (StringUtils.equalsIgnoreCase("S", head.getRespType())) {
			result.setSuccess(true);
		} else {
			result.setErrorMsg(head.getRespMsg());
			result.setResultCode(head.getRespCode());
		}
		return result;
	}

	@Override
	public Result getCheckAccountFile(FileDownReq obj) throws GopayException {
		BaseBisBankExtConfig bankConfig = bankIntrChannConfService.findBaseBisBankExtConfigByBankChannel(
				BisBankBusinessProd._16, BisBankInterfaceChannel._17, BankConstants.BANK_LOGO_WECHAT);
		Result result = new Result();
		TransMsg<FetchCheckAccntFile> response = (TransMsg<FetchCheckAccntFile>) cmbcWechatScanPayManager
				.getCheckAccountFile(obj.getDate(), obj.getFileType(), generateFileParam(bankConfig,BankConstants.BANK_LOGO_WECHAT));
		logger.info("---民生扫码获取对账文件返回处理对象：" + ToStringBuilder.reflectionToString(response));
		result.setDefaultModel(response.getBody());
		Head head = response.getHead();
		if (StringUtils.equalsIgnoreCase("S", head.getRespType())) {
			result.setSuccess(true);
		} else {
			result.setErrorMsg(head.getRespMsg());
			result.setResultCode(head.getRespCode());
			result.setSuccess(false);
		}
		return result;
	}
	public Result getCheckAlipayAccountFile(FileDownReq obj) throws GopayException {
		BaseBisBankExtConfig bankConfig = bankIntrChannConfService.findBaseBisBankExtConfigByBankChannel(
				BisBankBusinessProd._16, BisBankInterfaceChannel._17, BankConstants.BANK_LOGO_ALIPAY);
		Result result = new Result();
		TransMsg<FetchCheckAccntFile> response = (TransMsg<FetchCheckAccntFile>) cmbcWechatScanPayManager
				.getCheckAccountFile(obj.getDate(), obj.getFileType(), generateFileParam(bankConfig,BankConstants.BANK_LOGO_ALIPAY));
		logger.info("---民生扫码获取支付宝对账文件返回处理对象：" + ToStringBuilder.reflectionToString(response));
		result.setDefaultModel(response.getBody());
		Head head = response.getHead();
		if (StringUtils.equalsIgnoreCase("S", head.getRespType())) {
			result.setSuccess(true);
		} else {
			result.setErrorMsg(head.getRespMsg());
			result.setResultCode(head.getRespCode());
			result.setSuccess(false);
		}
		return result;
	}
	public Map<String, String> generateParam(BaseBisBankExtConfig bankConfig) {
		Map<String, String> param = new HashMap<String, String>();
		param.put("privateKeyPath", bankConfig.getIntrMerPravkeyPath());
		param.put("publicKeyPath", bankConfig.getIntrBankPubkeyPath());
		param.put("url", bankConfig.getPayUrl());
		return param;
	}
	public Map<String, String> generateFileParam(BaseBisBankExtConfig bankConfig,String bankCode) {
		Map<String, String> param = new HashMap<String, String>();
		param.put("privateKeyPath", bankConfig.getIntrMerPravkeyPath());
		param.put("publicKeyPath", bankConfig.getIntrBankPubkeyPath());
		param.put("url", bankConfig.getPayUrl());
		param.put("payType", bankCode);
		return param;
	}

	@Override
	public Result merchantOperation(Object msg) throws GopayException {
		BaseBisBankExtConfig bankConfig = bankIntrChannConfService.findBaseBisBankExtConfigByBankChannel(
				BisBankBusinessProd._16, BisBankInterfaceChannel._17, BankConstants.BANK_LOGO_WECHAT);
		MerchantOperation request = (MerchantOperation) msg;
		TransMsg<MerchantOperation> response = (TransMsg) cmbcWechatScanPayManager.merchantOperation(request,
				generateParam(bankConfig));
		logger.info("---民生扫码商户配置返回处理对象：" + ToStringBuilder.reflectionToString(response));
		Result result = new Result();	
		Head head = response.getHead();
		result.setDefaultModel(response.getBody());
		if (StringUtils.equalsIgnoreCase("S", head.getRespType())) {
			result.setSuccess(true);
			result.setOrderStatus(true);
			result.setModel("flag", "S");
		}else if(StringUtils.equalsIgnoreCase("R", head.getRespType())){
			result.setSuccess(true);
			result.setOrderStatus(false);
			result.setModel("flag", "R");
			result.setErrorMsg(head.getRespMsg());
			result.setResultCode(head.getRespCode());
		}
		else {
			result.setModel("flag", "E");
			result.setSuccess(true);
			result.setOrderStatus(false);
			result.setErrorMsg(head.getRespMsg());
			result.setResultCode(head.getRespCode());
		}
		return result;
	}

	@Override
	public Result merchantOperationQuery(Object msg) throws GopayException {
		BaseBisBankExtConfig bankConfig = bankIntrChannConfService.findBaseBisBankExtConfigByBankChannel(
				BisBankBusinessProd._16, BisBankInterfaceChannel._17, BankConstants.BANK_LOGO_WECHAT);

		MerchantOperationQuery request = (MerchantOperationQuery) msg;
		TransMsg<MerchantOperationQuery> response = (TransMsg) cmbcWechatScanPayManager.merchantOperationQuery(request,
				generateParam(bankConfig));
		logger.info("---民生扫码商户配置查询返回处理对象：" + ToStringBuilder.reflectionToString(response));
		Result result = new Result();
		result.setDefaultModel(response.getBody());
		Head head = response.getHead();
		if (StringUtils.equalsIgnoreCase("S", head.getRespType())) {
			/**
			 * 判断审核失败的情况
			 */
			if(StringUtils.equalsIgnoreCase("S", response.getBody().getOriRespType())){
				result.setSuccess(true);
				result.setErrorMsg(response.getBody().getOriRespMsg());
				result.setResultCode(response.getBody().getOriRespCode());
				result.setModel("flag", "S");
			}else if(StringUtils.equalsIgnoreCase("R", response.getBody().getOriRespType())){
				result.setSuccess(true);
				result.setErrorMsg(response.getBody().getOriRespMsg());
				result.setResultCode(response.getBody().getOriRespCode());
				result.setModel("flag", "R");
			}else{
				result.setSuccess(true);
				result.setErrorMsg(response.getBody().getOriRespMsg());
				result.setResultCode(response.getBody().getOriRespCode());
				result.setModel("flag", "E");
			}
		} else {
			result.setSuccess(false);
			result.setErrorMsg(head.getRespMsg());
			result.setResultCode(head.getRespCode());
		}
		return result;
	}
}
